<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>模态框</title>
    <style>
        #modal {
            height: 200px;
            width: 200px;
            line-height: 200px;
            position: fixed;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
            border: 1px solid black;
            text-align: center;
            background: pink;
        }
    </style>
</head>

<body>
    <button id="open">打开模态框</button>
    <button id="close">关闭模态框</button>
    <script>
        // modal 不是要提前存在的
        // modal 等到需要出现时，最好 开始生产+显示
        // 推迟 Modal 的实例化时间 到第一次需求
        // 用 只需要实例化一个对象————单例模式！
        // const Modal = function () {
        //     // dom -> body
        //     this.modalBox = document.createElement('div');
        //     this.modalBox.id = 'modal';
        //     this.modalBox.style.display = 'none';
        //     this.modalBox.innerHTML = '我是全局唯一的Mdoal';
        //     document.body.appendChild(this.modalBox);
        // }
        // modal 是全局唯一的，不需要new 多个
        // let modal = null;//放在全局，以便访问->but 闭包试试

        // 这样写也不好：
        // 触发与否 modal 都已经挂载在页面上了
        // let modal = document.createElement('div');
        // modal.id = 'modal';
        // modal.style.display = 'none';
        // modal.innerHTML = '我是全局唯一的Mdoal';
        // document.body.appendChild(modal);

        // 构建 Modal 类：
        // 1. 立即执行函数 + 返回函数
        //  函数嵌套函数--闭包
        const Modal = (function () {
            let modal = null;// 属于立即执行函数作用域———— 为什么第一次执行之后都不执行这一句了呢？
            // 当立即执行函数返回函数的时候，返回的函数内需要的modal，是通过作用域链向外找到这里的modal的
            console.log('outer', modal);

            // 返回一个函数 以便new
            // 因为只要实例化一个对象，所以去掉this
            return function () {
                if (!modal) { // 区分第一次实例化和之后的实例化,第一次实例化的时候设置属性
                    modal = document.createElement('div');
                    modal.id = 'modal';
                    modal.style.display = 'none';
                    modal.innerHTML = '我是全局唯一的Mdoal';
                    document.body.appendChild(modal);
                    console.log('first', modal);
                }
                console.log('inner', modal, this);
                return modal;
            }
        })();// 为什么一定要用立即执行函数呢？

        console.log(Modal);

        const openButton = document.getElementById('open'),
            closeButton = document.getElementById('close');

        // 单例模式：无论实例化多少次，返回的任然是原来的唯一的实例
        openButton.addEventListener('click', function () {
            let modal = new Modal(); //局部，访问有问题->闭包实现
            // modal = new Modal();//全局
            // console.log(modal);
            modal.style.display = 'block';
        });
        closeButton.addEventListener('click', function () {
            let modal = new Modal();
            // console.log(modal);// 可以访问到modal，即使没有new———— 所以modal挂载在哪里了呢？ 可以访问，但是不规范 容易出问题
            modal.style.display = 'none';
        });
        // console.log(modal);// 全局访问不到

    </script>
</body>

</html>